#include <SFML/Window.hpp>
#include <SFML/System.hpp>
#include <SFML/Graphics.hpp>
#include "Environment/WorldModel.h"
#include "Agents/Soldier.h"
#include "Formation/VFormation.h"
#include "Formation/LineFormation.h"
#include <vector>
#include <iostream>
#include "Obstacles/StaticObstacleStone.h"

int main(int argc, char** argv){
    //Création de l'environnement
    WorldModel* wm = new WorldModel(800,600);
    std::vector<Soldier*> soldiers;
    //std::vector<Stone*> stones;

    FormationBody *formationBody = new LineFormation();
    formationBody->scale(5);

    //Création soldat
    Soldier *s1 = new Soldier(formationBody, 0);
    //Ajout body dans l'environnement
    wm->addAgentBody(s1->getBody());
    s1->getBody()->setPosition(10,500);
    soldiers.push_back(s1);


    //Création soldat
    Soldier *s2 = new Soldier(formationBody, 1);
    //Ajout body dans l'environnement
    wm->addAgentBody(s2->getBody());
    s2->getBody()->setPosition(200,0);
    soldiers.push_back(s2);

    //Création soldat
    Soldier *s3 = new Soldier(formationBody, 2);
    //Ajout body dans l'environnement
    wm->addAgentBody(s3->getBody());
    s3->getBody()->setPosition(800,100);
    soldiers.push_back(s3);

    //Création soldat
    Soldier *s4 = new Soldier(formationBody, 3);
    //Ajout body dans l'environnement
    wm->addAgentBody(s4->getBody());
    s4->getBody()->setPosition(200,10);
    soldiers.push_back(s4);

    //Création soldat
    Soldier *s5 = new Soldier(formationBody, 4);
    //Ajout body dans l'environnement
    wm->addAgentBody(s5->getBody());
    s5->getBody()->setPosition(20,100);
    soldiers.push_back(s5);

    StaticObstacleStone *stone1 = new StaticObstacleStone(10);
    wm->addObstacle(stone1);
    stone1->setPosition(700,50);
    //stones.push_back(stone1);

    StaticObstacleStone *stone2 = new StaticObstacleStone(20);
    wm->addObstacle(stone2);
    stone2->setPosition(500,400);
    //stones.push_back(stone2);

    StaticObstacleStone *stone3 = new StaticObstacleStone(10);
    wm->addObstacle(stone3);
    stone3->setPosition(600,300);
    //stones.push_back(stone3);


    StaticObstacleStone *stone4 = new StaticObstacleStone(20);
    wm->addObstacle(stone4);
    stone4->setPosition(300,30);
    //stones.push_back(stone3);


    StaticObstacleStone *stone5 = new StaticObstacleStone(20);
    wm->addObstacle(stone5);
    stone5->setPosition(60,300);
    //stones.push_back(stone3);


    StaticObstacleStone *stone6 = new StaticObstacleStone(5);
    wm->addObstacle(stone6);
    stone6->setPosition(60,100);
    //stones.push_back(stone3);


    //Création de la fenêtre
    sf::RenderWindow App(sf::VideoMode(800, 600), "String");
    bool Running = true;

    //Boucle de la fenêtre
    while(Running)
    {
        wm->runBehaviour();
        for(int i=0;i<soldiers.size();++i){
            soldiers[i]->live();
        }

        //On applique les influences
        wm->applyInfluences();

        //On efface l'image
        App.Clear();

        std::vector<FormationSlot*> fs = formationBody->getSlots();
        for (int i = 0; i < fs.size(); i++)
            App.Draw(sf::Shape::Circle(fs[i]->getGlobalPosition().x(),fs[i]->getGlobalPosition().y(),5,sf::Color::Black,1,sf::Color::Red));

        std::vector<AbstractSituatedObject*> stones = wm->getSituatedObjects();
        for(int i = 0;i<stones.size();++i){
            App.Draw(sf::Shape::Circle(stones[i]->getX(),stones[i]->getY(),stones[i]->getSize(),sf::Color(92,92,92),0,sf::Color::Red));
        }


        sf::Event Event;
        while (App.GetEvent(Event))
        {
            // Fenêtre fermée
            if (Event.Type == sf::Event::Closed)
             Running = false;

            // Touche 'echap' appuyée
            if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Escape))
                Running = false;
        }
        //Récupération des bodies
        std::vector<AgentBody*> ab = wm->getAgentBodies();
        for(int i = 0;i<ab.size();++i){
            App.Draw(sf::Shape::Circle(ab[i]->getX(),ab[i]->getY(),10,sf::Color::Blue,0,sf::Color::Red));

            App.Draw(sf::Shape::Line(ab[i]->getX(),ab[i]->getY(),ab[i]->getX()+cos(ab[i]->getAngle())*10,ab[i]->getY()+sin(ab[i]->getAngle())*10,2,sf::Color::White,2,sf::Color::Blue));
        }
        //Dessin des bodies
        App.Display();
    }
    for(int i=0;i<soldiers.size();++i){
        delete soldiers[i];
    }

    soldiers.clear();

    delete formationBody;
    delete wm;

    return 0;
}
